package net.ebakker.subtitles;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.googlecode.opensubtitlesjapi.LANGUAGE;
import com.googlecode.opensubtitlesjapi.OpenSubtitlesAPI;
import com.googlecode.opensubtitlesjapi.OpenSubtitlesException;

public class SubtitleDownloader {

	private static OpenSubtitlesAPI subtitlesAPI;
	private static String token;

	private SubtitleDownloader() {

	}

	public static Map<LANGUAGE, Boolean> downloadSubtitles(File episode, String username,
			String password, List<LANGUAGE> languages) throws OpenSubtitlesException, IOException {
		if (subtitlesAPI == null) {
			subtitlesAPI = new OpenSubtitlesAPI();
			token = subtitlesAPI.login(username, password);
		}

		return download(episode, languages);

	}

	private static Map<LANGUAGE, Boolean> download(File episode, List<LANGUAGE> languages)
			throws OpenSubtitlesException, IOException {
		List<Map<String, Object>> result =
				subtitlesAPI.search(token, episode,
						languages.toArray(new LANGUAGE[languages.size()]));

		Map<LANGUAGE, Boolean> success = new HashMap<>();
		for (LANGUAGE lang : languages) {
			success.put(lang, new Boolean(downloadSubtitle(result, lang, episode)));
		}
		return success;

	}

	public String logIn(String username, String password) throws OpenSubtitlesException {
		return subtitlesAPI.login(username, password);
	}

	private static boolean downloadSubtitle(List<Map<String, Object>> result, LANGUAGE lang,
			File episode) throws OpenSubtitlesException, IOException {
		System.out.println(result.size() + " subtitles found");
		for (Map<String, Object> subtitle : result) {

			if (!subtitle.get("SubLanguageID").equals(lang.toString().toLowerCase())) {
				continue;
			}
			System.out.println("Downloading " + lang.toString() + " subtitle for "
					+ episode.getName());
			downloadFile(subtitle, episode);
			return true;
		}

		return false;

	}

	private static void downloadFile(Map<String, Object> subtitle, File episode)
			throws OpenSubtitlesException, IOException {
		Map<Integer, byte[]> download = subtitlesAPI.download(token, getSubtitleId(subtitle));

		FileOutputStream fw =
				new FileOutputStream(episode.getAbsolutePath().replace("mkv",
						subtitle.get("LanguageName") + ".srt"));
		try {
			for (byte[] b : download.values()) {
				fw.write(b);
			}
			return;
		} finally {
			fw.flush();
			fw.close();
		}

	}

	private static Integer getSubtitleId(Map<String, Object> subtitle) {
		Object object = subtitle.get("IDSubtitleFile");
		return Integer.valueOf((String)object);
	}

	public static void logOut() throws OpenSubtitlesException {
		if (subtitlesAPI != null) {
			subtitlesAPI.logout(token);
		}
	}
}
